package cn.aws360.boot.system.starter.controller;

import cn.aws360.boot.base.api.annotation.OpsLog;
import cn.aws360.boot.base.api.constant.enums.OpsTypeEnum;
import cn.aws360.boot.base.api.pojo.response.ResultModel;
import cn.aws360.boot.base.api.utils.ServletUtils;
import cn.aws360.boot.base.api.validation.ValidationGroup;
import cn.aws360.boot.data.api.pojo.request.PageQuery;
import cn.aws360.boot.data.api.pojo.response.PageResult;
import cn.aws360.boot.system.api.pojo.request.SysMenuQuery;
import cn.aws360.boot.system.api.pojo.request.SysMenuWrite;
import cn.aws360.boot.system.api.pojo.response.SysMenuModel;
import cn.aws360.boot.system.biz.service.SysMenuService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static cn.aws360.boot.system.api.constant.SysConstant.*;

/**
 * @author junnan
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/sys/menu")
@ApiSupport(order = MODULE_MENU_CODE)
@Api(value = MODULE_MENU_NAME, tags = MODULE_MENU_TAGS)
public class SysMenuController {

    private final SysMenuService menuService;

    @GetMapping("/index.json")
    @SaCheckPermission("sys:menu:query")
    @ApiOperation(value = "菜单页面", hidden = true)
    public ResultModel<JSONObject> index() {
        return ResultModel.ok(ServletUtils.getPageJson());
    }

    @GetMapping("/list")
    @SaCheckPermission("sys:menu:query")
    @ApiOperation(value = "菜单列表")
    @ApiOperationSupport(order = 1)
    public ResultModel<List<SysMenuModel>> list(SysMenuQuery sysMenuQuery) {
        return ResultModel.ok(menuService.findList(sysMenuQuery));
    }

    @GetMapping("/page")
    @SaCheckPermission("sys:menu:query")
    @ApiOperation(value = "菜单分页")
    @ApiOperationSupport(order = 1)
    public ResultModel<PageResult<SysMenuModel>> page(SysMenuQuery sysMenuQuery, PageQuery pageQuery) {
        return ResultModel.ok(menuService.findPage(sysMenuQuery, pageQuery));
    }

    @GetMapping("/tree")
    @SaCheckPermission("sys:menu:query")
    @ApiOperation(value = "菜单树形")
    @ApiOperationSupport(order = 1)
    public ResultModel<List<Tree<Integer>>> tree(SysMenuQuery sysMenuQuery) {
        return ResultModel.ok(menuService.findTree(sysMenuQuery));
    }

    @GetMapping("/{id}")
    @SaCheckPermission("sys:menu:detail")
    @ApiOperation(value = "菜单详情")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParam(name = "id", value = "菜单 id", dataTypeClass = Integer.class, required = true)
    public ResultModel<SysMenuModel> detail(@PathVariable Integer id) {
        return ResultModel.ok(menuService.detail(id));
    }

    @PostMapping
    @SaCheckPermission("sys:menu:add")
    @OpsLog(title = "新增菜单", opsType = OpsTypeEnum.INSERT)
    @ApiOperation(value = "新增菜单")
    @ApiOperationSupport(order = 2)
    public ResultModel<Boolean> add(@Validated(ValidationGroup.add.class) @RequestBody SysMenuWrite sysMenuWrite) {
        return ResultModel.ok(menuService.add(sysMenuWrite));
    }

    @PutMapping()
    @SaCheckPermission("sys:menu:edit")
    @OpsLog(title = "修改菜单", opsType = OpsTypeEnum.UPDATE)
    @ApiOperation(value = "修改菜单")
    @ApiOperationSupport(order = 3)
    public ResultModel<Boolean> edit(@Validated(ValidationGroup.edit.class) @RequestBody SysMenuWrite sysMenuWrite) {
        return ResultModel.ok(menuService.edit(sysMenuWrite));
    }

    @DeleteMapping("/{ids}")
    @SaCheckPermission("sys:menu:remove")
    @OpsLog(title = "移除菜单", opsType = OpsTypeEnum.REMOVE)
    @ApiOperation(value = "移除菜单")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParam(name = "ids", value = "菜单 ids", dataTypeClass = String.class, required = true)
    public ResultModel<Boolean> remove(@PathVariable String ids) {
        return ResultModel.ok(menuService.remove(ids));
    }

}
